package com.liulishuo.demo.filedownloaderapplication;


import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadQueueSet;
import com.liulishuo.filedownloader.FileDownloader;
import com.liulishuo.filedownloader.model.FileDownloadStatus;
import com.liulishuo.filedownloader.notification.BaseNotificationItem;
import com.liulishuo.filedownloader.notification.FileDownloadNotificationHelper;
import com.liulishuo.filedownloader.notification.FileDownloadNotificationListener;
import com.liulishuo.filedownloader.util.FileDownloadUtils;
import com.oszc.bbhmlibrary.utils.LogUtil;
import com.oszc.bbhmlibrary.utils.MainHandler;
import com.oszc.bbhmlibrary.utils.ResUtil;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Checkbox;
import ohos.agp.components.Component;
import ohos.agp.components.ProgressBar;
import ohos.bundle.ElementName;
import ohos.event.intentagent.IntentAgent;
import ohos.event.intentagent.IntentAgentConstant;
import ohos.event.intentagent.IntentAgentHelper;
import ohos.event.intentagent.IntentAgentInfo;
import ohos.event.notification.NotificationHelper;
import ohos.event.notification.NotificationRequest;
import ohos.event.notification.NotificationSlot;
import ohos.global.resource.NotExistException;
import ohos.rpc.RemoteException;

import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class NotificationSampleAbility extends Ability {
    public final String TAG = NotificationSampleAbility.class.getSimpleName();
    private final FileDownloadNotificationHelper<NotificationItem> notificationHelper =
            new FileDownloadNotificationHelper<>();
    private NotificationListener listener;

    private final String savePath = FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "notification";
    private final String url = Constant.LIULISHUO_APK_URL;
    private final int channelId = 381;
    private NotificationSlot slot;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_layout_notification_sample);

        assignViews();

        slot = Utils.createNotificationChannel(channelId + "", "FileDownloader");
        listener = new NotificationListener(new WeakReference<>(this), channelId, slot);
    }

    public void onClickStart(final Component view) {
        LogUtil.error(TAG, String.format("onClickStart [view]"));
        startDownload.setEnabled(false);
        final FileDownloadQueueSet queueSet = new FileDownloadQueueSet(listener);
        final List<BaseDownloadTask> tasks = new ArrayList<>();
        final int taskCount = 5;
        for (int i = 0; i < taskCount; i++) {
            tasks.add(FileDownloader.getImpl()
                    .create(Constant.URLS[i])
                    .setTag(i + 1)
                    .setPath(savePath, true)
            );
        }
        queueSet.downloadTogether(tasks)
                .addTaskFinishListener(new BaseDownloadTask.FinishListener() {
                    final AtomicInteger counter = new AtomicInteger();

                    @Override
                    public void over(BaseDownloadTask task) {
                        final int finishCount = counter.addAndGet(1);
                        if (finishCount == taskCount) MainHandler.post(() -> {
                            startDownload.setEnabled(true);
                            progressBar.setIndeterminate(false);
                            progressBar.setProgressValue(1);
                            progressBar.setMaxValue(1);
                        });
                    }
                })
                .start();
        progressBar.setIndeterminate(true);
    }

    public void onClickPause(final Component view) {
        LogUtil.error(TAG, String.format("onClickPause [view]"));
        FileDownloader.getImpl().pause(listener);
    }

    @SuppressWarnings("ResultOfMethodCallIgnored")
    public void onClickDelete(final Component view) {
        LogUtil.error(TAG, String.format("onClickDelete [view]"));
        FileDownloader.getImpl().pause(listener);
        new Thread(new Runnable() {
            @Override
            public void run() {
                final File file = new File(savePath);
                if (file.isFile()) file.delete();
                if (file.exists()) {
                    final File[] files = file.listFiles();
                    if (files == null) return;
                    for (File f : files) {
                        f.delete();
                    }
                    file.delete();
                }
            }
        }).start();
    }

    private static class NotificationListener extends FileDownloadNotificationListener {
        public final String TAG = NotificationListener.class.getSimpleName();
        private final int channelId;
        private final WeakReference<NotificationSampleAbility> wActivity;
        private NotificationSlot slot;

        public NotificationListener(
                WeakReference<NotificationSampleAbility> wActivity,
                int channelId,
                NotificationSlot slot
        ) {
            super(wActivity.get().notificationHelper);
            LogUtil.error(TAG, String.format("NotificationListener [wActivity, channelId, slot]"));
            this.wActivity = wActivity;
            this.channelId = channelId;
            this.slot = slot;
        }

        @Override
        protected BaseNotificationItem create(BaseDownloadTask task) {
            LogUtil.error(TAG, String.format("create [task]"));
            return new NotificationItem(
                    slot,
                    task.getId(),
                    "Task-" + task.getId(),
                    "",
                    channelId
            );
        }

        @Override
        public void addNotificationItem(BaseDownloadTask task) {
            super.addNotificationItem(task);
            if (wActivity.get() != null) {
                wActivity.get().showNotificationCb.setEnabled(false);
            }
        }

        @Override
        public void destroyNotification(BaseDownloadTask task) {
            super.destroyNotification(task);
            if (wActivity.get() != null) {
                wActivity.get().showNotificationCb.setEnabled(true);
            }
        }

        @Override
        protected boolean interceptCancel(BaseDownloadTask task,
                                          BaseNotificationItem n) {
            // in this demo, I don't want to cancel the notification, just show for the test
            // so return true
            return true;
        }

        @Override
        protected boolean disableNotification(BaseDownloadTask task) {
            boolean disableNotification = false;
            if (wActivity.get() != null) {
                disableNotification = !wActivity.get().showNotificationCb.isChecked();
            }else {
                disableNotification = super.disableNotification(task);
            }
             LogUtil.error(TAG,String.format("disableNotification %B",disableNotification));
            return  disableNotification;
            //return false;
        }
    }

    public static class NotificationItem extends BaseNotificationItem {
        public final String TAG = NotificationItem.class.getSimpleName();
        private final NotificationRequest builder;

        private NotificationItem(NotificationSlot slot, int id, String title, String desc, int channelId) {
            super(id, title, desc);
            LogUtil.error(TAG, String.format("NotificationItem [slot, id, title, desc, channelId]"));
            Intent mainAbilityIntent = Intent.makeMainAbility(new ElementName("", FileDownloaderApplication.instance.getBundleName(), MainAbility.class.getCanonicalName()));
            Intent sampleAbilityIntent = new Intent();
            Intent.OperationBuilder intent2Builder = new Intent.OperationBuilder();
            intent2Builder
                    .withDeviceId("")
                    .withBundleName(FileDownloaderApplication.instance.getBundleName())
                    .withAbilityName(NotificationSampleAbility.class.getCanonicalName());
            sampleAbilityIntent.setOperation(intent2Builder.build());

            /*
            final PendingIntent pendingIntent = PendingIntent.getActivities(
                    DemoApplication.CONTEXT, 0, intents,
                    PendingIntent.FLAG_UPDATE_CURRENT);
             */

            List<IntentAgentConstant.Flags> flags = new ArrayList<>();
            flags.add(IntentAgentConstant.Flags.UPDATE_PRESENT_FLAG);
            List<Intent> intentList = new ArrayList<>();
            intentList.add(mainAbilityIntent);
            intentList.add(sampleAbilityIntent);
            IntentAgentInfo intentAgentInfo = new IntentAgentInfo(200, IntentAgentConstant.OperationType.START_ABILITY, flags, intentList, null);
            IntentAgent intentAgent = IntentAgentHelper.getIntentAgent(FileDownloaderApplication.instance.getContext(), intentAgentInfo);

            NotificationRequest request = new NotificationRequest(channelId);
            NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
            content.setTitle(getTitle()).setText(desc);
            NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
            try {
                request.setLittleIcon(ResUtil.createByResourceId(FileDownloaderApplication.instance.getContext().getResourceManager(), ResourceTable.Media_icon, "icon"));
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NotExistException e) {
                e.printStackTrace();
            }
            request.setContent(notificationContent); // 设置通知的内容
            request.setIntentAgent(intentAgent); // 设置通知的 IntentAgent
            request.setSlotId(slot.getId());

            builder = request;
            /*
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                builder = new NotificationCompat.Builder(
                        FileDownloadHelper.getAppContext(),
                        channelId);
            } else {
                //noinspection deprecation
                builder = new NotificationCompat.Builder(FileDownloadHelper.getAppContext())
                        .setDefaults(Notification.DEFAULT_LIGHTS)
                        .setPriority(NotificationCompat.PRIORITY_MIN);
            }

            builder.setContentTitle(getTitle())
                    .setContentText(desc)
                    .setContentIntent(pendingIntent)
                    .setSmallIcon(R.mipmap.ic_launcher);
             */
        }

        @Override
        public void show(boolean statusChanged, int status, boolean isShowProgress) {
            LogUtil.error(TAG, String.format("show [statusChanged, status, isShowProgress]"));
            String desc = "";
            switch (status) {
                case FileDownloadStatus.pending:
                    desc += " pending";
                    builder.setProgressBar(getSofar(), getTotal(), true);
                    break;
                case FileDownloadStatus.started:
                    desc += " started";
                    builder.setProgressBar(getSofar(), getTotal(), true);
                    break;
                case FileDownloadStatus.progress:
                    desc += " progress";
                    builder.setProgressBar(getSofar(), getTotal(), getTotal() <= 0);
                    break;
                case FileDownloadStatus.retry:
                    desc += " retry";
                    builder.setProgressBar(getSofar(), getTotal(), true);
                    break;
                case FileDownloadStatus.error:
                    desc += " error";
                    builder.setProgressBar(getSofar(), getTotal(), false);
                    break;
                case FileDownloadStatus.paused:
                    desc += " paused";
                    builder.setProgressBar(getSofar(), getTotal(), false);
                    break;
                case FileDownloadStatus.completed:
                    desc += " completed";
                    builder.setProgressBar(getSofar(), getTotal(), false);
                    break;
                case FileDownloadStatus.warn:
                    desc += " warn";
                    builder.setProgressBar(0, 0, true);
                    break;
            }

            NotificationRequest.NotificationNormalContent content = new NotificationRequest.NotificationNormalContent();
            content.setTitle(getTitle()).setText(desc);
            NotificationRequest.NotificationContent notificationContent = new NotificationRequest.NotificationContent(content);
            builder.setContent(notificationContent);

            //builder.setContentTitle(getTitle()).setContentText(desc);
            //getManager().notify(getId(), builder.build());
            try {
                LogUtil.error(TAG, String.format("show [statusChanged, status, isShowProgress]"));
                NotificationHelper.publishNotification(builder, null);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        notificationHelper.clear();
        Utils.deleteNotificationChannel(channelId);
    }

    private Checkbox showNotificationCb;
    private ProgressBar progressBar;
    private Component startDownload;
    private Component stopDownload;
    private Component cancelNotification;

    private void assignViews() {
        showNotificationCb = (Checkbox) findComponentById(ResourceTable.Id_show_notification_cb);
        showNotificationCb.setChecked(true);
        progressBar = (ProgressBar) findComponentById(ResourceTable.Id_progressBar);
        startDownload = findComponentById(ResourceTable.Id_bt_start);
        startDownload.setClickedListener(view -> {
            onClickStart(view);
        });
        stopDownload = findComponentById(ResourceTable.Id_bt_stop);
        stopDownload.setClickedListener(view -> {
            onClickPause(view);
        });
        cancelNotification = findComponentById(ResourceTable.Id_bt_cancel);
        cancelNotification.setClickedListener(view -> {
            onClickDelete(view);
        });
    }
}
